Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Graphics /
Chapter 2 - Geometric Shapes / Using Geometric Shapes


Editing Polygon Parts

QuickDraw GX provides six functions that allow sophisticated editing of geometric shapes:

This section gives examples of the GXGetPolygonParts and GXSetPolygonParts functions. The next two sections show how to edit path shape geometries and shape geometries in general.

Listing 2-27 creates a polygon shape with two contours. Later examples in this section use this polygon shape to demonstrate editing polygon parts.

Listing 2-27 Creating a polygon shape with two contours

void CreateTwoAngles(void)
{
   gxShape     aPolygonShape;

   static long twoAngleGeometry[] = {2, /* number of contours */
                                     3, /* number of points */
                                     ff(100), ff(150), 
                                     ff(50), ff(100), 
                                     ff(100), ff(50),
                                     3, /* number of points */
                                     ff(200), ff(50), 
                                     ff(250), ff(100), 
                                     ff(200), ff(150)};
      

   aPolygonShape = GXNewPolygons((gxPolygons *) 
                                  twoAngleGeometry);
   GXSetShapeFill(aPolygonShape, gxOpenFrameFill);

   GXDrawShape(aPolygonShape);

   GXDisposeShape(aPolygonShape);
}
The result of this sample function is shown in Figure 2-52.

Figure 2-52 A polygon shape with two contours

The GXGetPolygonParts function allows you to extract geometric points from the geometry of an existing polygon shape and put them into a new polygon geometry. This function takes four parameters:

The GXGetPolygonParts function returns as its function result the number of bytes necessary to contain the extracted polygon. Therefore, you typically call GXGetPolygonParts twice--once to determine the size of extracted polygon and once to extract the polygon. For example, if you declare the variable

long     byteCount;
you could determine the number of bytes necessary to extract the top half of the polygon geometry in Figure 2-52 using this line of code:

byteCount = GXGetPolygonParts(aPolygonsShape, 2, 4, nil);
In this example, setting the final parameter to nil indicates that you want to determine the number of bytes necessary to hold the extracted polygon geometry, but you do not want to actually extract the polygon geometry. The values of 2 and 4 for the second and third parameters indicate that the GXGetPolygonParts function should determine the number of bytes necessary to hold an extracted polygon geometry that contains geometric points 2, 3, 4, and 5 from the polygon geometry in Figure 2-52.

You can then use this byte count to allocate enough memory to hold the extracted polygon geometry:

gxPolygons  *topHalfGeometry;
topHalfGeometry = (gxPolygons *) NewPtr(byteCount);
Finally, you can extract the polygon geometry by calling GXGetPolygonParts again:

GXGetPolygonParts(aPolygonsShape, 2, 4, topHalfGeometry);
The sample function in Listing 2-28 creates the polygon shape from the previous example, extracts the second through the fifth geometric points and puts them into a separate geometry, and then replaces the geometry of the original polygon shape with the extracted geometry.

Listing 2-28 Extracting part of a polygon shape

void ExtractTopPartOfPolygon(void)
{
   gxShape     aPolygonShape;

   static long twoAngleGeometry[] = {2, /* number of contours */
                                     3, /* number of points */
                                     ff(100), ff(150),
                                     ff(50), ff(100),
                                     ff(100), ff(50),
                                     3, /* number of points */
                                     ff(200), ff(50),
                                     ff(250), ff(100),
                                     ff(200), ff(150)};

   long     byteCount;

   gxPolygons *topHalfGeometry;

   aPolygonShape = GXNewPolygons((gxPolygons *) 
                                  twoAngleGeometry);
   GXSetShapeFill(aPolygonShape, gxOpenFrameFill);

   byteCount =  GXGetPolygonParts(aPolygonShape, 2, 4, nil);
   topHalfGeometry = (gxPolygons *) NewPtr(byteCount);
   GXGetPolygonParts(aPolygonShape, 2, 4, topHalfGeometry);

   GXSetPolygons(aPolygonShape, topHalfGeometry);

   GXDrawShape(aPolygonShape);

   GXDisposeShape(aPolygonShape);
}
The resulting polygon shape is shown in Figure 2-53.

Figure 2-53 A polygon shape extracted from a larger polygon shape

Compare this polygon shape with the polygon shape shown in Figure 2-52.

Like the GXSetShapePoints function discussed in the previous section, the GXSetPolygonParts function allows you to replace geometric points within a polygon shape's geometry. However, the GXSetPolygonParts function allows you even more editing control. With it, you can also remove geometric points, insert geometric points, and break a polygon shape into multiple contours.

As an example of replacing geometric points in a polygon geometry, the sample function in Listing 2-29 creates two polygon geometries: the two-angle polygon geometry from Figure 2-52 and another polygon geometry consisting of a single point. The sample function creates the two-angle polygon shape as in Listing 2-27 and then replaces its third and fourth geometric points with the single geometric point of the other polygon
geometry.

Listing 2-29 Replacing geometric points of a polygon shape

void ReplaceControlPoints(void)
{
   gxShape     aPolygonShape;

   static long twoAngleGeometry[] = {2, /* number of contours */
                                     3, /* number of points */
                                     ff(100), ff(150), 
                                     ff(50), ff(100), 
                                     ff(100), ff(50),
                                     3, /* number of points */
                                     ff(200), ff(50), 
                                     ff(250), ff(100), 
                                     ff(200), ff(150)};
                                
   static long newTopGeometry[] = {1, /* number of contours */
                                   1, /* number of points */
                                   ff(150), ff(50)};
      

   aPolygonShape = GXNewPolygons((gxPolygons *) 
                                 twoAngleGeometry);
   GXSetShapeFill(aPolygonsShape, gxOpenFrameFill);

   GXSetPolygonParts(aPolygonShape, 3, 2, 
                     (gxPolygons *) newTopGeometry,
                     gxBreakNeitherEdit);

   GXDrawShape(aPolygonShape);

   GXDisposeShape(aPolygonShape);
}
Figure 2-54 shows the result of the sample function in Listing 2-29.

Figure 2-54 A polygon with two geometric points replaced by a single geometric point

Notice that, whereas the GXSetShapePoints function limited you to replacing geometric points on a point-by-point basis, the GXSetPolygonParts function allows you to replace any number of geometric points in the original geometry with any number of new geometric points contained in an arbitrary polygon geometry.

Since the GXSetPolygonParts function allows you to insert an arbitrary polygon geometry into the geometry of an existing polygon shape, you can use this function to break a single polygon contour into multiple contours. In fact, the final parameter to GXSetPolygonParts allows you to specify how the resulting polygons shape should be broken up. In the previous example, the gxBreakNeitherEdit constant indicated that the resulting polygon should not be broken into separate contours.

The next example, shown in Listing 2-30, first creates a polygon shape similar to the two-angle polygons shape, except in this example the two contours are connected, as shown in Figure 2-55.

Figure 2-55 A polygon shape with one contour

The sample function then uses the GXSetPolygonParts function to insert a new geometric point in the center of the polygon.

Listing 2-30 Inserting a geometric point in a polygon shape

void CreateHollowPolygon(void)
{
   gxShape     aPolygonShape;

   static long twoAngleGeometry[] = {1, /* number of contours */
                                     6, /* number of points */
                                     ff(100), ff(150), 
                                     ff(50), ff(100), 
                                     ff(100), ff(50),
                                     ff(200), ff(50), 
                                     ff(250), ff(100), 
                                     ff(200), ff(150)};
                                
   static long newCenterGeometry[] = {1, /* number of contours */
                                      1 /* number of points */,
                                      ff(150), ff(100)};
      

   aPolygonShape = GXNewPolygons((gxPolygons *) 
                                  twoAngleGeometry);
   GXSetShapeFill(aPolygonShape, gxClosedFrameFill);

   GXSetPolygonParts(aPolygonShape, 4, 0, 
                     (gxPolygons *) newCenterGeometry,
                     gxBreakNeitherEdit);

   GXDrawShape(aPolygonShape);

   GXDisposeShape(aPolygonShape);
}
Since this sample function specifies the gxBreakNeitherEdit constant as the final parameter to the GXSetPolygonParts function, the resulting polygon has a single contour, as shown in Figure 2-56.

Figure 2-56 A polygon shape edited with the gxBreakNeitherEdit flag set

However, if the sample function had specified the gxBreakLeftEdit constant, as with the call

GXSetPolygonParts(aPolygonsShape, 4, 0, 
                 (gxPolygons *) newCenterGeometry, 
                 gxBreakLeftEdit);
QuickDraw GX would break the resulting polygon into two contours: The gxBreakLeftEdit constant indicates that the polygon should be broken between the newly inserted point and the previous point, as shown in Figure 2-57.

Figure 2-57 A polygon shape edited with the gxBreakLeftEdit flag set

The gxBreakRightEdit constant works similarly, except the break occurs between the newly inserted point and the subsequent point, as shown in Figure 2-58.

Figure 2-58 A polygon shape edited with the gxBreakRightEdit flag set

You can use the GXSetPolygonParts function to insert a polygon geometry that contains multiple contours. In this case, the breaks that occur in the inserted geometry remain in the resulting polygon shape.

For more information about polygon geometries, see "Polygon Shapes" on page 2-22.

For more information about the GXGetPolygonParts and GXSetPolygonParts functions, see the function descriptions on page 2-144 and page 2-145.

The next two sections show more examples of editing shape geometries.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996